﻿using BenCaoXuan.Infrastructure.Attr;
using BenCaoXuan.Infrastructure.Dto.Middle.Request.Appointment;
using BenCaoXuan.Infrastructure.Dto;
using BenCaoXuan.Infrastructure.EFCore.MySql;
using BenCaoXuan.Infrastructure.IOC;
using BenCaoXuan.Service.Interface.middle;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using BenCaoXuan.Infrastructure.Tools;
using MySqlX.XDevAPI.Common;
using BenCaoXuan.Infrastructure.Dto.Middle.Response.Appointment;
using BenCaoXuan.Infrastructure.Dto.Middle.Response.Product;
using ServiceStack.Script;

namespace BenCaoXuan.Service.Instance.middle
{
    [Inject_]
    public class Appointment_Service : Base_Service, I_Appointment_Service
    {
        private readonly Appointment_IOC _appointment_IOC;
        private readonly Product_IOC _product_IOC;

        public Appointment_Service(Appointment_IOC appointment_IOC, Product_IOC product_IOC)
        {
            _appointment_IOC = appointment_IOC;
            _product_IOC = product_IOC;
        }
        /// <summary>
        /// 重新预约
        /// </summary>
        /// <param name="appointmentId"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Rebook_Appointment(string? appointmentId)
        {
            var appointment = await _appointment_IOC._appointment_EFCore.GetAll()
                .FirstOrDefaultAsync(a => a.AId == appointmentId);

            if (appointment == null)
            {
                return Get_Result(-1, "预约记录不存在");
            }
            appointment.AStatus = 0;
            _appointment_IOC._appointment_EFCore.Update(appointment);
            await _appointment_IOC._appointment_EFCore.SaveChangesAsync();
            return Get_Result(0, "重新预约成功");
        }

        /// <summary>
        /// 取消预约
        /// </summary>
        /// <param name="appointmentId"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Cancel_Appointment(string? appointmentId)
        {
            var appointment = await _appointment_IOC._appointment_EFCore.GetAll().FirstOrDefaultAsync(a => a.AId == appointmentId);
            if (appointment == null)
            {
                return Get_Result(-1, "预约记录不存在");
            }
            appointment.AStatus = -1;
            _appointment_IOC._appointment_EFCore.Update(appointment); // 显式标记为已修改
            await _appointment_IOC._appointment_EFCore.SaveChangesAsync();
            return Get_Result(0, "取消成功");
        }

        /// <summary>
        /// 查询预约详情
        /// </summary>
        /// <param name="appointmentId"></param>
        /// <param name="isProduct"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Get_AppointmentDetails(string? appointmentId, bool isProduct)
        {
            if (string.IsNullOrEmpty(appointmentId))
            {
                return Get_Result(-1, "预约ID不能为空");
            }

            var appointment = await _appointment_IOC._appointment_EFCore
                .GetAll(a => a.AId == appointmentId).FirstOrDefaultAsync();

            if (appointment == null)
            {
                return Get_Result(0, "未查询到该预约记录");
            }

            string name = isProduct ? "未知产品" : "未知套餐";
            string targetId = isProduct ? appointment.AProductId : appointment.APackageId; // 区分产品/套餐ID

            if (!string.IsNullOrEmpty(targetId))
            {
                if (isProduct)
                {
                    // 产品预约：通过【规格ID】查规格表 → 再查产品表
                    var productSpec = await _product_IOC._productSpecs_EFCore
                        .GetAll(ps => ps.PsId == targetId).FirstOrDefaultAsync();

                    if (productSpec != null)
                    {
                        var product = await _product_IOC._product_EFCore
                            .GetAll(p => p.PId == productSpec.PsProductId).FirstOrDefaultAsync();
                        if (product != null)
                        {
                            name = product.PName ?? $"未命名产品 (ID: {targetId})";
                        }
                    }
                }
                else
                {
                    // 套餐预约：直接通过【套餐ID】查套餐表
                    var package = await _product_IOC._productPackage_EFCore
                        .GetAll(p => p.PpId == targetId).FirstOrDefaultAsync();
                    if (package != null)
                    {
                        name = package.PpName ?? $"未命名套餐 (ID: {targetId})";
                    }
                }
            }

            var data = new AppointmentDetails_Response_Dto
            {
                appointmentId = appointment.AId,
                name = name,
                time = appointment.ATime,
                period = appointment.APeriod?.ToString("yyyy-MM-dd") ?? "未设置",
                money = appointment.AMoney ?? 0,
            };

            return Get_Result(0, "查询成功", data);
        }
        /// <summary>
        /// 立即预约-套餐
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Add_Appointment(Appointment_Request_Dto dto)
        {
            // 检查是否已存在相同时间的预约
            var exists = await _appointment_IOC._appointment_EFCore
                .GetAll(a => a.APackageId == dto.packageId
                            && a.APeriod == dto.period
                            && a.ATime == dto.time)
                .SingleOrDefaultAsync();

            // 如果已存在相同预约，返回错误
            if (exists != null)
            {
                return Get_Result(-1, "该时段已被预约，请选择其他时间");
            }



            // 创建预约实体 
            Appointment appointment = new Appointment
            {
                AId = Config.GenerateTId(),
                ACustomerId = dto.customerId,
                ACustomerName = dto.customerName ?? string.Empty,
                APhone = dto.phone ?? string.Empty,
                APackageId = dto.packageId,
                ATime = dto.time,
                AMoney = dto.money ?? 0,
                APeriod = dto.period!.Value.Date,
                AStatus = 0,
                AIsOrder = 0,
                AVisit = 0,
                AProductId=""
            };

            // 保存到数据库
            _appointment_IOC._appointment_EFCore.Add(appointment);
            await _appointment_IOC._appointment_EFCore.SaveChangesAsync();
            return Get_Result(0, "预约成功", appointment);
        }

        /// <summary>
        /// 立即预约-产品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Add_Product_Appointment(Appointment_Request_Dto dto)
        {
            // 检查是否已存在相同时间的预约
            var exists = await _appointment_IOC._appointment_EFCore
                .GetAll(a => a.AProductId == dto.productId
                            && a.APeriod == dto.period
                            && a.ATime == dto.time)
                .SingleOrDefaultAsync();

            // 如果已存在相同预约，返回错误
            if (exists != null)
            {
                return Get_Result(-1, "该时段已被预约，请选择其他时间");
            }

            // 创建预约实体 
            Appointment appointment = new Appointment
            {
                AId = Config.GenerateTId(),
                ACustomerId = dto.customerId,
                ACustomerName = dto.customerName ?? string.Empty,
                APhone = dto.phone ?? string.Empty,
                AProductId = dto.productId,
                ATime = dto.time,
                AMoney = dto.money ?? 0,
                APeriod = dto.period!.Value.Date,
                AStatus = 0,
                AIsOrder = 0,
                APackageId="",
                AVisit=0
            };

            // 保存到数据库
            _appointment_IOC._appointment_EFCore.Add(appointment);
            await _appointment_IOC._appointment_EFCore.SaveChangesAsync();

            return Get_Result(0, "预约成功", appointment);
        }

        /// <summary>
        /// 获取客户的所有预约
        /// </summary>
        /// <param name="customerId"></param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Get_Customer_Appointment(string? customerId)
        {
            if (string.IsNullOrEmpty(customerId))
            {
                return Get_Result(-1, "客户ID不能为空");
            }

            var appointments = await _appointment_IOC._appointment_EFCore.GetAll()
                .Where(a => a.ACustomerId == customerId)
                .ToListAsync();

            if (!appointments.Any())
            {
                return Get_Result(0, "该客户暂无预约记录");
            }

            var productSpecIds = new List<string>();
            foreach (var appointment in appointments)
            {
                if (!string.IsNullOrEmpty(appointment.AProductId))
                {
                    productSpecIds.AddRange(appointment.AProductId.Split(',').Where(id => !string.IsNullOrEmpty(id)));
                }
            }
            productSpecIds = productSpecIds.Distinct().ToList();

            var packageIds = new List<string>();
            foreach (var appointment in appointments)
            {
                if (!string.IsNullOrEmpty(appointment.APackageId))
                {
                    packageIds.AddRange(appointment.APackageId.Split(',').Where(id => !string.IsNullOrEmpty(id)));
                }
            }
            packageIds = packageIds.Distinct().ToList();

            var productSpecs = await _product_IOC._productSpecs_EFCore.GetAll()
                .Where(ps => productSpecIds.Contains(ps.PsId))
                .ToListAsync();

            var productIds = productSpecs.Select(ps => ps.PsProductId).Distinct().ToList();

            var products = await _product_IOC._product_EFCore.GetAll()
                .Where(p => productIds.Contains(p.PId))
                .ToDictionaryAsync(p => p.PId, p => p);

            var packages = await _product_IOC._productPackage_EFCore.GetAll()
                .Where(p => packageIds.Contains(p.PpId))
                .ToDictionaryAsync(p => p.PpId, p => p);

            //var pspecs = productSpecs.Select(d => d.PsName);
            var appointmentDtos = new List<Appointment_Response_Dto>();
            foreach (var appointment in appointments)
            {
                var productNames = new List<string>();
                if (!string.IsNullOrEmpty(appointment.AProductId))
                {
                    var specIds = appointment.AProductId.Split(',').Where(id => !string.IsNullOrEmpty(id)).ToList();
                    var specs = productSpecs.Where(ps => specIds.Contains(ps.PsId)).ToList();
                    foreach (var spec in specs)
                    {

                        if (products.TryGetValue(spec.PsProductId!, out var product))
                        {
                            productNames.Add(product.PName ?? "未知产品");
                        }
                        else
                        {
                            productNames.Add("产品信息缺失");
                        }
                    }
                }


                var packageNames = new List<string>();
                if (!string.IsNullOrEmpty(appointment.APackageId))
                {
                    var pkgIds = appointment.APackageId.Split(',').Where(id => !string.IsNullOrEmpty(id)).ToList();
                    foreach (var pkgId in pkgIds)
                    {
                        if (packages.TryGetValue(pkgId, out var pkg))
                        {
                            packageNames.Add(pkg.PpName ?? "未知套餐");
                        }
                        else
                        {
                            packageNames.Add("套餐信息缺失");
                        }
                    }
                }

                appointmentDtos.Add(new Appointment_Response_Dto
                {
                    AppointmentId = appointment.AId,
                    CustomerName = appointment.ACustomerName ?? "未知客户",
                    Phone = appointment.APhone ?? "未知电话",
                    AppointmentPeriod = appointment.APeriod?.ToString("yyyy-MM-dd") ?? "未知日期",
                    AppointmentTime = appointment.ATime ?? "未知时间",
                    Money = appointment.AMoney ?? 0,
                    ProductNames = productNames, // 直接传列表
                    PackageNames = packageNames, // 直接传列表
                    Status = GetStatusText(appointment.AStatus ?? -2)
                });
            }

            return Get_Result(0, "查询成功", appointmentDtos);
        }

        private string GetStatusText(int status)
        {
            switch (status)
            {
                case 0:
                    return "已预约";
                case 1:
                    return "已完成";
                case -1:
                    return "已取消";
                default:
                    return "状态未知";
            }
        }


        /// <summary>
        /// 获取客户最近三条预约记录
        /// </summary>
        /// <param name="customerId">客户ID</param>
        /// <returns></returns>
        public async Task<Api_Result_Dto> Get_Customer_LatestThreeAppointments(string? customerId)
        {
            if (string.IsNullOrEmpty(customerId))
            {
                return Get_Result(-1, "客户ID不能为空");
            }

            var appointments = await _appointment_IOC._appointment_EFCore.GetAll()
                .Where(a => a.ACustomerId == customerId)
                .OrderByDescending(a => a.APeriod)
                .Take(3)
                .ToListAsync();

            if (!appointments.Any())
            {
                return Get_Result(0, "该客户暂无预约记录");
            }

            var productSpecIds = new List<string>();
            foreach (var appointment in appointments)
            {
                if (!string.IsNullOrEmpty(appointment.AProductId))
                {
                    productSpecIds.AddRange(appointment.AProductId.Split(',').Where(id => !string.IsNullOrEmpty(id)));
                }
            }
            productSpecIds = productSpecIds.Distinct().ToList();

            var packageIds = new List<string>();
            foreach (var appointment in appointments)
            {
                if (!string.IsNullOrEmpty(appointment.APackageId))
                {
                    packageIds.AddRange(appointment.APackageId.Split(',').Where(id => !string.IsNullOrEmpty(id)));
                }
            }
            packageIds = packageIds.Distinct().ToList();

            var productSpecs = await _product_IOC._productSpecs_EFCore.GetAll()
                .Where(ps => productSpecIds.Contains(ps.PsId))
                .ToListAsync();

            var productIds = productSpecs.Select(ps => ps.PsProductId).Distinct().ToList();

            var products = await _product_IOC._product_EFCore.GetAll()
                .Where(p => productIds.Contains(p.PId))
                .ToDictionaryAsync(p => p.PId, p => p);

            var packages = await _product_IOC._productPackage_EFCore.GetAll()
                .Where(p => packageIds.Contains(p.PpId))
                .ToDictionaryAsync(p => p.PpId, p => p);

            var appointmentDtos = new List<Appointment_Response_Dto>();
            foreach (var appointment in appointments)
            {
                var productAndSpecNames = new List<string>();
                if (!string.IsNullOrEmpty(appointment.AProductId))
                {
                    var specIds = appointment.AProductId.Split(',').Where(id => !string.IsNullOrEmpty(id)).ToList();
                    var specs = productSpecs.Where(ps => specIds.Contains(ps.PsId)).ToList();
                    foreach (var spec in specs)
                    {
                        string productName = "产品信息缺失";
                        if (products.TryGetValue(spec.PsProductId!, out var product))
                        {
                            productName = product.PName ?? "未知产品";
                        }
                        // 拼接产品名称和规格名称
                        productAndSpecNames.Add($"{productName}-{spec.PsName ?? "未知规格"}");
                    }
                }

                var packageNames = new List<string>();
                if (!string.IsNullOrEmpty(appointment.APackageId))
                {
                    var pkgIds = appointment.APackageId.Split(',').Where(id => !string.IsNullOrEmpty(id)).ToList();
                    foreach (var pkgId in pkgIds)
                    {
                        if (packages.TryGetValue(pkgId, out var pkg))
                        {
                            packageNames.Add(pkg.PpName ?? "未知套餐");
                        }
                        else
                        {
                            packageNames.Add("套餐信息缺失");
                        }
                    }
                }

                appointmentDtos.Add(new Appointment_Response_Dto
                {
                    AppointmentId = appointment.AId,
                    CustomerName = appointment.ACustomerName ?? "未知客户",
                    Phone = appointment.APhone ?? "未知电话",
                    AppointmentPeriod = appointment.APeriod?.ToString("yyyy-MM-dd") ?? "未知日期",
                    AppointmentTime = appointment.ATime ?? "未知时间",
                    Money = appointment.AMoney ?? 0,
                    ProductNames = productAndSpecNames, // 现在包含产品和规格名称
                    PackageNames = packageNames,
                    Status = GetStatusText2(appointment.AStatus ?? -2)
                });
            }

            return Get_Result(0, "查询成功", appointmentDtos);
        }

        private string GetStatusText2(int statusCode)
        {
            switch (statusCode)
            {
                case 0:
                    return "已预约";
                case 1:
                    return "已完成";
                case -1:
                    return "已取消";
                default:
                    return "未知状态";
            }
        }
    }
}
